package com.controller;


import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.commonutils.RandomUtil;
import com.commonutils.results;
import com.entity.pojo.Categories;
import com.entity.pojo.Courses;
import com.service.CategoriesService;
import com.service.CoursesService;
import com.utils.InitData;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/courses")
@CrossOrigin
public class CoursesController {
    @Resource
    private CoursesService coursesService;

    @Resource
    private InitData initData;

    @Resource
    private CategoriesService categoriesService;

    @ApiOperation("查询所有的课程名称和id")
    @GetMapping("/getCoursesIdAndName")
    public results getCoursesIdAndName() {
        List<Courses> allCoursesIdAndNameList = coursesService.list(new QueryWrapper<Courses>()
                .select("courseId", "courseName"));
        return results.ok().data("allCoursesIdAndNameList", allCoursesIdAndNameList);
    }

    @ApiOperation("组合条件查询课程信息")
    @PostMapping("/pageCoursesCondition/{current}/{limit}")
    public results pageCoursesCondition(@PathVariable long current,
                                        @PathVariable long limit,
                                        @RequestBody(required = false) Courses courses) {
        Page<Courses> pageCourses = new Page<>(current, limit);
        QueryWrapper<Courses> coursesWrapper = new QueryWrapper<>();
        validateCondition(coursesWrapper, courses);
        coursesService.page(pageCourses, coursesWrapper);
        long total = pageCourses.getTotal();
        List<Courses> coursesRecords = pageCourses.getRecords();
        return results.ok().data("rows", coursesRecords).data("total", total);
    }

    @ApiOperation("校验课程的组合查询条件")
    private void validateCondition(QueryWrapper<Courses> wrapper, Courses courses) {
        Integer courseId = courses.getCourseId();
        String courseCode = courses.getCourseCode();
        String courseName = courses.getCourseName();
        String nextCourseStr = courses.getNextCourseStr();
        String propertiesKey = courses.getPropertiesKey();
        String propertiesValue = courses.getPropertiesValue();
        String createdByName = courses.getCreatedByName();
        Date beginTime = courses.getCreateTime();
        Date updateTime = courses.getUpdateTime();

        if (courseId != null)
            wrapper.eq("courseId", courseId);
        if (StringUtils.hasText(courseCode))
            wrapper.like("courseCode", courseCode);
        if (StringUtils.hasText(courseName))
            wrapper.like("courseName", courseName);
        if (StringUtils.hasText(nextCourseStr))
            wrapper.like("nextCourseStr", nextCourseStr);
        if (StringUtils.hasText(propertiesKey))
            wrapper.like("propertiesKey", propertiesKey);
        if (StringUtils.hasText(propertiesValue))
            wrapper.like("propertiesValue", propertiesValue);
        if (StringUtils.hasText(createdByName))
            wrapper.like("createdByName", createdByName);
        if (!StringUtils.isEmpty(beginTime))
            wrapper.ge("createTime", beginTime);
        if (!StringUtils.isEmpty(updateTime))
            wrapper.le("updateTime", updateTime);
    }

    //todo 在加入security框架后还需要添加创建人的信息
    @ApiOperation("增加新的课程")
    @PostMapping("addCourse")
    public results addCourse(@RequestBody Courses course) {
        if (!StringUtils.hasText(course.getCourseName())) {
            return results.error("课程名称不能为空");
        }
        initCourse(course);
        boolean saveFlag = coursesService.save(course);
        if (saveFlag) {
            return results.ok();
        } else {
            return results.error("增加分组信息失败");
        }
    }

    private void initCourse(Courses course) {
        // 设置课程代码
        Integer maxPrimaryId = coursesService.getOne(new QueryWrapper<Courses>().select("max(courseId)", "courseId")).getCourseId();
        String courseCode = "A" + RandomUtil.getSixBitRandom() + maxPrimaryId;
        course.setCourseCode(courseCode);
    }

    @ApiOperation("修改课程信息")
    @PutMapping("updateCourse")
    public results updateCourse(@RequestBody Courses course) {
        boolean updateFlag = coursesService.updateCoursesInfo(course);
        if (updateFlag) {
            return results.ok();
        } else {
            return results.error("修改课程信息失败");
        }
    }

    @ApiOperation("删除课程")
    @DeleteMapping("deleteCourse/{courseId}")
    public results deleteCourse(@PathVariable Integer courseId) {
        int count = categoriesService.count(new QueryWrapper<Categories>().eq("courseId", courseId));
        if (count != 0) {
            return results.error("请先删除该课程下的对应目录，再删除该课程！");
        }
        boolean removeFlag = coursesService.removeById(courseId);
        if (removeFlag) {
            return results.ok();
        } else {
            return results.error("删除信息失败");
        }
    }

    @ApiOperation("从Excel中导入课程信息，easyExcel版，")
    @PostMapping("/importCourseData")
    public results importCourseInfo(MultipartFile file) {
        if (file.isEmpty()) {
            return results.error("上传文件为空，请重新选择");
        }
        coursesService.importCourseInfo(file, coursesService, initData);
        return results.ok();
    }

    @ApiOperation("导出课程信息easyExcel版，无法使用swagger测试")
    @PostMapping(value = "/exportCourseData", produces = "application/octet-stream")
    public void exportCoursesData(HttpServletResponse response, @RequestBody(required = false) Integer[] courseIds) {
        // 获取数据
        List<Courses> resultList;
        if (courseIds == null || courseIds.length == 0) {
            resultList = coursesService.list();
        } else {
            resultList = (List<Courses>) coursesService.listByIds(Arrays.asList(courseIds));
        }
        try {
            //  设置内容格式 以及 编码方式
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            // 设置文件名称
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyExcel没有关系
            String fileName = URLEncoder.encode("课程表", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            //  sheet名称
            EasyExcel.write(response.getOutputStream(), Courses.class)
                    .sheet("课程表").doWrite(resultList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @ApiOperation("初始化Neo4j数据库，创建所有课程节点、课程关系，及课程节点下的目录节点")
    @GetMapping("initNeo4jDataBase")
    public results initNeo4jDataBase() {
        coursesService.transformCourseToCourseNode();
        coursesService.createAllCourseRelation();
        return results.ok();
    }

    @ApiOperation("获取Neo4j的所有节点及其相关关系")
    @GetMapping("/getAllNode")
    public results getAllNode() {
        return coursesService.getAllNodeAndRelation();
    }

}

